package com.millstein.baier.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期时间工具类
 * @author tsing
 * @date 2020年9月15日
 */
public class DateUtil {

	private static final String pattern = "yyyy-MM-dd HH:mm:ss";

	public static String dealDateFormat(String dateTime) throws Exception {
		String result ="";
		if(dateTime.contains("Z")) {
			dateTime = dateTime.replace("Z", " UTC");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
			SimpleDateFormat defaultFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		
			Date time = format.parse(dateTime);
			result = defaultFormat.format(time);
		}
		else
		{
			result=dateTime.substring(0, 10);
		}
			
		return result;
	}
	
	/**
	 * 时间戳转为日期类型
	 * @author tsing
	 * @date 2020年6月24日
	 * @param timestamp
	 * @return
	 */
	public static String timestampToDateStr(Long timestamp) {
        Date date = new Date(timestamp);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = dateFormat.format(date);
        return format;
    }
	
	/**
	 * 获取当前到本月月底的秒数
	 * @author tsing
	 * @date 2020年9月5日
	 * @return
	 */
	public static Integer getNowToThisMonthRemainSeconds() {
		
		// 1.获取本月的最后一天的日期
		String year = getCurrentYear();
		String month = getCurrentMonth();
		String lastDay = getLastDayOfMonth(year, month);
		
		String lastDate = year + "-" + month + "-" + lastDay + " 23:59:59";

		// 2.获取最后一天结束时的毫秒值
		Date date = ConcurrentUtil.parse(lastDate, pattern);
		long mills = date.getTime();
		
		// 3.获取当前的毫秒值
		long nowMills = System.currentTimeMillis();
		
		return (int) ((mills - nowMills) / 1000);
	}
	
	/**
	 * 获取当前到本日结束的秒数
	 * @author tsing
	 * @date 2020年9月5日
	 * @return
	 */
	public static Integer getNowToTodayRemainSeconds() {
		// 1.获取今天的日期
		String year = getCurrentYear();
		String month = getCurrentMonth();
		String day = getCurrentDay();
		String today = year + "-" + month + "-" + day + " 23:59:59";
		
		// 2.获取今天结束时的毫秒值
		Date date = ConcurrentUtil.parse(today, pattern);
		long mills = date.getTime();
		
		// 3.获取当前的毫秒值
		long nowMills = System.currentTimeMillis();
		
		return (int) ((mills - nowMills) / 1000);
	}
	
	/**
	 * 获取月底的日期
	 * @author tsing
	 * @date 2020年9月5日
	 * @param year
	 * @param month
	 * @return
	 */
	public static String getLastDayOfMonth(String year, String month) {
	    Calendar cal = Calendar.getInstance();
	    //年
	    cal.set(Calendar.YEAR, Integer.parseInt(year));
	    //月，因为Calendar里的月是从0开始，所以要-1
	    cal.set(Calendar.MONTH, Integer.parseInt(month) - 1);
	    //日，设为一号
	    cal.set(Calendar.DATE, 1);
	    //月份加一，得到下个月的一号
	    cal.add(Calendar.MONTH,1);
	    //下一个月减一为本月最后一天
	    cal.add(Calendar.DATE, -1);
	    return String.valueOf(cal.get(Calendar.DAY_OF_MONTH));//获得月末是几号
	}
	
	/**
	 * 获取当前年
	 * @author tsing
	 * @date 2020年9月5日
	 * @return
	 */
	public static String getCurrentYear() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.YEAR) + "";
	}
	
	/**
	 * 获取当前月
	 * @author tsing
	 * @date 2020年9月5日
	 * @return
	 */
	public static String getCurrentMonth() {
		Calendar cal = Calendar.getInstance();
		String month = cal.get(Calendar.MONTH) + 1 + "";
		return month.length() == 1 ? "0" + month : month;
	}
	
	/**
	 * 获取当前日
	 * @author tsing
	 * @date 2020年9月5日
	 * @return
	 */
	public static String getCurrentDay() {
		Calendar cal = Calendar.getInstance();
		String day = cal.get(Calendar.DATE) + "";
		return day.length() == 1 ? "0" + day : day;
	}
	
	/**
	 * 根据时间戳获取时间字符串，格式为yyyy-MM-dd HH:mm:ss
	 * @author tsing
	 * @date 2020年10月22日
	 * @param timestamp 指定时间戳
	 * @return
	 */
	public static String getAssignTimeStrByTimestamp(long timestamp) {
		Date date = new Date(timestamp);
		String dateStr = ConcurrentUtil.format(date, pattern);
		return dateStr;
	}

	/**
	 * 根据时间戳获取对应的年份
	 * @author tsing
	 * @date 2020年10月22日
	 * @param timestamp 指定时间戳
	 * @return
	 */
	public static String getAssignYearByTimestamp(long timestamp) {
		String dateStr = getAssignTimeStrByTimestamp(timestamp);
		return dateStr.substring(0, 4);
	}
	
	/**
	 * 根据时间戳获取对应的月份
	 * @author tsing
	 * @date 2020年10月22日
	 * @param timestamp 指定时间戳
	 * @return
	 */
	public static String getAssignMonthByTimestamp(long timestamp) {
		String dateStr = getAssignTimeStrByTimestamp(timestamp);
		return dateStr.substring(5, 7);
	}
	
	/**
	 * 根据时间戳获取对应的天
	 * @author tsing
	 * @date 2020年10月22日
	 * @param timestamp 指定时间戳
	 * @return
	 */
	public static String getAssignDayByTimestamp(long timestamp) {
		String dateStr = getAssignTimeStrByTimestamp(timestamp);
		return dateStr.substring(8, 10);
	}
	
	/**
	 * 获取两个时间之间的毫秒值
	 * @author tsing
	 * @date 2020年9月15日
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public static long getTimeIntervalOfMillSeconds(Date startTime, Date endTime) {
		long diff = endTime.getTime() - startTime.getTime();
//		if (diff < 0) {
//			throw new RuntimeException("起始时间不能大于结束时间");
//		}
		return diff;
	}
	
	/**
	 * 获取两个时间间隔查多少天
	 * @author tsing
	 * @date 2020年9月15日
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public static int getTimeIntervalOfDays(Date startTime, Date endTime) {
		Long day = getTimeIntervalOfMillSeconds(startTime, endTime) / (1000 * 24 * 60 * 60);
		return day.intValue();
	}
	
	/**
	 * 获取两个时间间隔查多少个小时
	 * @author tsing
	 * @date 2020年9月15日
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public static int getTimeIntervalOfHours(Date startTime, Date endTime) {
		Long hour = getTimeIntervalOfMillSeconds(startTime, endTime) / (1000 * 60 * 60);
		return hour.intValue();
	}
	
	/**
	 * 获取两个时间间隔查多少分钟
	 * @author tsing
	 * @date 2020年9月15日
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public static int getTimeIntervalOfMinutes(Date startTime, Date endTime) {
		Long minute = getTimeIntervalOfMillSeconds(startTime, endTime) / (1000 * 60);
		return minute.intValue();
	}
	
	/**
	 * 获取两个时间差多少秒钟
	 * @author tsing
	 * @date 2020年9月15日
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 */
	public static long getTimeIntervalOfSeconds(Date startTime, Date endTime) {
		Long second = getTimeIntervalOfMillSeconds(startTime, endTime) / 1000;
		return second;
	}
	/**
	 * 获取days天之后的日期，如果days为负值，查询的就是days之前的日期
	 * @param days
	 * @return
	 */
	public static String getDateByDay(int days) {
		Calendar calendar1 = Calendar.getInstance();
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		calendar1.add(Calendar.DATE, days);
		String date = sdf1.format(calendar1.getTime());
		return date;
		  
	}
	
	/**
	 * 获取日期，从今天开始往后number天
	 * @author tsing
	 * @date 2020年9月24日
	 * @param number 往后几天
	 * @return
	 */
	public static String getDateAfterNumber(int number) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, number);
		Date time = cal.getTime();
		return ConcurrentUtil.format(time, pattern).substring(0, 10);
	}

	/**
	 * 获取明天的日期
	 * @return
	 */
	public static String getNextDate() {
		return getDateAfterNumber(1);
	}
	
	/**
	 * 获取今天的日期
	 * @author tsing
	 * @date 2020年9月24日
	 * @return
	 */
	public static String getTodayDate() {
		return ConcurrentUtil.format(new Date(), pattern).substring(0, 10);
	}
	
	/**
	 * 获取上个月第一天的第一秒
	 * @author tsing
	 * @date 2020年10月20日
	 * @return
	 */
	public static Long getFirstSecondForLastMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		 
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		String date = ConcurrentUtil.format(calendar.getTime(), pattern).substring(0, 10) + " 00:00:00";
		return ConcurrentUtil.parse(date, pattern).getTime();
	}
	
	/**
	 * 获取上个月的最后一天的最后一秒
	 * @author tsing
	 * @date 2020年10月20日
	 * @return
	 */
	public static Long getLastSecondForLastMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1); 
		calendar.add(Calendar.DATE, -1);
		String date = ConcurrentUtil.format(calendar.getTime(), pattern).substring(0, 10) + " 23:59:59";
		return ConcurrentUtil.parse(date, pattern).getTime();
	}
	
	/**
	 * 获取本月第一天的第一秒
	 * @author tsing
	 * @date 2020年10月20日
	 * @return
	 */
	public static Long getFirstSecondForThisMonth() {
		Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0); //获取当前月第一天
        c.set(Calendar.DAY_OF_MONTH, 1); //设置为1号,当前日期既为本月第一天
        c.set(Calendar.HOUR_OF_DAY, 0); //将小时至0
        c.set(Calendar.MINUTE, 0); //将分钟至0
        c.set(Calendar.SECOND,0); //将秒至0
        c.set(Calendar.MILLISECOND, 0); //将毫秒至0
        return c.getTimeInMillis();
	}
	
	/**
	 * 获取本月的最后一天的最后一秒
	 * @author tsing
	 * @date 2020年10月20日
	 * @return
	 */
	public static Long getLastSecondForThisMonth() {
		Calendar c2 = Calendar.getInstance();
        c2.set(Calendar.DAY_OF_MONTH, c2.getActualMaximum(Calendar.DAY_OF_MONTH)); //获取当前月最后一天
        c2.set(Calendar.HOUR_OF_DAY, 23); //将小时至23
        c2.set(Calendar.MINUTE, 59); //将分钟至59
        c2.set(Calendar.SECOND, 59); //将秒至59
        c2.set(Calendar.MILLISECOND, 000);
        return c2.getTimeInMillis();
	}

	/**
	 * 获取上个月的年月信息，输出信息为202010，表示2020年10月
	 * @author tsing
	 * @date 2020年10月20日
	 * @return
	 */
	public static String getLastMonthStr() {
        Date date = new Date();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        
        return ConcurrentUtil.format(cal.getTime(), pattern).substring(0, 7).replaceAll("-", "");
	}

	/**
	 * 获取一周前的日期（包括今天在内的7天）
	 * @return
	 */
	public static String getLastWeekStrWithToday() {
		Calendar c = Calendar.getInstance();
		//过去七天
		c.setTime(new Date());
		c.add(Calendar.DATE, - 6);
		Date d = c.getTime();
		return ConcurrentUtil.format(d).substring(0, 10);
	}

	/**
	 * 获取一周前的日期（不包括今天在内的7天）
	 * @return
	 */
	public static String getLastWeekStrWithoutToday() {
		Calendar c = Calendar.getInstance();
		//过去七天
		c.setTime(new Date());
		c.add(Calendar.DATE, - 7);
		Date d = c.getTime();
		return ConcurrentUtil.format(d).substring(0, 10);
	}

	/**
	 * 获取昨天的日期
	 * @return
	 */
	public static String getYesterdayDay() {
		Calendar c = Calendar.getInstance();
		//过去七天
		c.setTime(new Date());
		c.add(Calendar.DATE, - 1);
		Date d = c.getTime();
		return ConcurrentUtil.format(d).substring(0, 10);
	}

	/**
	 * 返回指定的时间段内的有所日期
	 *
	 * @param startDate 开始时间,例:2016-02-25
	 * @param endDate   结束时间,例:2016-03-05
	 * @return 注意，输出的是不含年份的
	 */
	public static List<String> dateSplit(String startDate, String endDate) {
		List<String> dateList = new ArrayList<>();
		Date newStartDate;
		newStartDate = ConcurrentUtil.parse(startDate, "yyyy-MM-dd");
		Date newEndDate = ConcurrentUtil.parse(endDate, "yyyy-MM-dd");
		Long spi = newEndDate.getTime() - newStartDate.getTime();
		Long step = spi / (24 * 60 * 60 * 1000);// 相隔天数
		List<Date> newDateList = new ArrayList<>();
		newDateList.add(newStartDate);
		dateList.add(startDate.substring(5, 10));
		for (int i = 1; i <= step; i++) {
			dateList.add(ConcurrentUtil.format(new Date(newDateList.get(i - 1).getTime() + (24 * 60 * 60 * 1000)), "MM-dd"));
			newDateList.add(new Date(newDateList.get(i - 1).getTime() + (24 * 60 * 60 * 1000)));// 比上一天+一
		}
		return dateList;
	}

	/**
	 * 将毫秒转为小时分秒
	 * @author tsing
	 * @date 2020年10月21日
	 * @param time 毫秒数
	 * @return
	 */
	public static String getGapTime(long time) {
        long hours = time / (1000 * 60 * 60);
        long minutes = (time - hours * (1000 * 60 * 60 )) / (1000* 60);
        long seconds = (time - hours * (1000 * 60 * 60 ) - minutes * (1000 * 60)) / 1000;
        String hourStr = hours + "";
        String minuteStr = minutes + "";
        String secondStr = seconds + "";
        
        return (hourStr.length() == 1 ? "0" + hourStr : hourStr) + ":" 
        	+ (minuteStr.length() == 1 ? "0" + minuteStr : minuteStr) + ":" 
        	+ (secondStr.length() == 1 ? "0" + secondStr : secondStr);
    }
	
	public static int getLastDayByYearMonthStr(String yearMonthStr) {
		int year = Integer.parseInt(yearMonthStr.split("-")[0]);  //年
		int month = Integer.parseInt(yearMonthStr.split("-")[1]); //月
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		// cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.MONTH, month); //设置当前月的上一个月
		// 获取某月最大天数
		//int lastDay = cal.getActualMaximum(Calendar.DATE);
		int lastDay = cal.getMinimum(Calendar.DATE); //获取月份中的最小值，即第一天
		// 设置日历中月份的最大天数
		//cal.set(Calendar.DAY_OF_MONTH, lastDay);
		cal.set(Calendar.DAY_OF_MONTH, lastDay - 1); //上月的第一天减去1就是当月的最后一天
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		return Integer.parseInt(sdf.format(cal.getTime()).substring(8));
	}
	
	/**
	 * 根据年月字符串，获取该月开始的时间字符串和结束的时间字符串
	 * @author tsing
	 * @date 2020年12月4日
	 * @param yearMonthStr 年月字符串，如2020-10，表示2020年10月
	 * @return
	 */
	public static Map<String, String> getStartAndEndTimeByYearMonthStr(String yearMonthStr) {
		// 根据时间字符串获取该月的最后一天
		int lastDay = getLastDayByYearMonthStr(yearMonthStr);
		// 计算该月第一刻
		StringBuilder sb = new StringBuilder();
		String startTime = sb.append(yearMonthStr).append("-01 00:00:00").toString();
		// 计算该月最后一刻
		sb = new StringBuilder();
		String endTime = sb.append(yearMonthStr).append("-").append(lastDay).append(" 23:59:59").toString();
		// 封装返回数据
		Map<String, String> returnMap = new HashMap<>();
		returnMap.put("startTime", startTime);
		returnMap.put("endTime", endTime);
		return returnMap;
	}	
}
